package hikari.instruments.navmesh;

import com.gooddies.wiring.annotations.WiringComponent;
import java.awt.Cursor;
import java.util.ArrayList;
import java.util.List;
import org.swig.jirr.ICustomizableTriangleMeshNode;
import org.swig.jirr.ISceneNode;
import org.swig.jirr.S3DVertex;

/**
 * @author Dmitry
 */
@WiringComponent
public class NavmeshDeletePointInstrument extends NavmeshInstrument {

    private ISceneNode selectedNode;

    private NavmeshDeletePointInstrument() {
    }

    @Override
    public void mouseDown(int x, int y, int button, int modifier) {
        super.mouseDown(x, y, button, modifier);
        if (selectedNode != null) {
            utils.setModified();
            deleteVertexBySphereNode(selectedNode);
        }
    }

    @Override
    public void mouseMove(int x, int y, int dx, int dy, int modifier) {
        selectedNode = trySelect(x, y);
        if (selectedNode == null) {
            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        } else {
            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        }
        super.mouseMove(x, y, dx, dy, modifier);
    }

    @Override
    public void instrumentActivate() {
        super.instrumentActivate();
        addMeshSelectorToAllSphereVertexes();
    }

    private boolean indexInArray(int[] array, int element) {
        for (int e : array) {
            if (e == element) {
                return true;
            }
        }
        return false;
    }

    private int ensureIndex(int currentIndex, int deleteIndex) {
        if (currentIndex >= deleteIndex) {
            return currentIndex - 1;
        }
        return currentIndex;
    }

    private void deleteVertexBySphereNode(ISceneNode node) {
        ICustomizableTriangleMeshNode triangleMeshNode = getMesh().getMeshSceneNode();
        int index = getIndex(node);
        int[] indexes = triangleMeshNode.getIndices();
        S3DVertex[] vertexes = triangleMeshNode.getVertices();
        node.remove();
        vertexes = (S3DVertex[]) utils.deleteArrayElement(vertexes, index);

        List<TriangleIndex> triangles = new ArrayList<>();
        for (int i = 0; i < indexes.length; i += 3) {
            TriangleIndex triangle = new TriangleIndex(new int[]{indexes[i], indexes[i + 1], indexes[i + 2]});
            if (!triangle.isContainIndex(index)) {
                triangles.add(triangle);
            }
        }

        int[] newIndexes = new int[triangles.size() * 3];
        int i = 0;
        for (TriangleIndex triangle : triangles) {
            newIndexes[i + 0] = ensureIndex(triangle.getIndexes()[0], index);
            newIndexes[i + 1] = ensureIndex(triangle.getIndexes()[1], index);
            newIndexes[i + 2] = ensureIndex(triangle.getIndexes()[2], index);
            i += 3;
        }

        triangleMeshNode.setIndices(newIndexes);
        triangleMeshNode.setVertices(vertexes);
        triangleMeshNode.recalculate();
        reread();
    }

    private void reread() {
        super.resetInstrument();
        addVertexSpheresArMeshVertexPositions();
        addMeshSelectorToAllSphereVertexes();
    }

    class TriangleIndex {

        int[] indexes;

        public TriangleIndex(int[] indexes) {
            this.indexes = indexes;
        }

        public int[] getIndexes() {
            return indexes;
        }

        public boolean isContainIndex(int index) {
            for (int i : indexes) {
                if (i == index) {
                    return true;
                }
            }
            return false;
        }
    }
}